package com.chaodev.base.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.chaodev.base.base.RedisDao;
import com.chaodev.base.dao.AttDao;
import com.chaodev.base.dao.CommDao;
import com.chaodev.base.dao.TrainingDao;
import com.chaodev.base.dto.TrainAttDto;
import com.chaodev.base.dto.TrainingAddDto;
import com.chaodev.base.dto.TrainingPageDto;
import com.chaodev.base.em.BizTypeEnum;
import com.chaodev.base.em.OperEnum;
import com.chaodev.base.model.*;
import com.chaodev.base.service.ILogService;
import com.chaodev.base.service.TrainingService;
import com.chaodev.base.utils.CodeGenerateUtil;
import com.chaodev.base.utils.JwtUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@Service
public class TrainingServiceImpl implements TrainingService {

    @Autowired
    private ILogService logService;
    @Autowired
    private RedisDao redisDao;

    @Autowired
    private TrainingDao trainingDao;
    @Autowired
    private AttDao attDao;
    @Autowired
    private CommDao commDao;

    @Override
    public Result page(TrainingPageDto dto, HttpServletRequest request) {
        Result result = new Result();
        String token = request.getHeader("token");
        UserInfo userInfo = null;
        if (redisDao.existsKey(token)) {
            userInfo = JwtUtil.getUserInfoFromToken(token, redisDao);
            Training training = new Training();
            BeanUtil.copyProperties(dto, training);
            if (null == dto.getPage()) {
                dto.setPage(1);
            }
            if (null == dto.getRows()) {
                dto.setRows(20);
            }
            PageHelper.startPage(dto.getPage(), dto.getRows());
            List<Training> tbTrainingList = trainingDao.queryDataList(training);
            PageInfo<Training> trainingList = new PageInfo<Training>(tbTrainingList, dto.getRows());
            result.setCode(200);
            result.setMsg("获取成功");
            result.setData(trainingList);
            logService.logAdd(null, "获取培训课程分页列表", "SUCCESS", result.toString(), userInfo, request);
        } else {
            result.setCode(-1);
            result.setMsg("登录超时");
            logService.logAdd(null, "获取培训课程分页列表", "ERROR", result.toString(), userInfo, request);
        }
        return result;
    }

    @Override
    public Result list(TrainingPageDto dto, HttpServletRequest request) {
        Result result = new Result();
        String token = request.getHeader("token");
        UserInfo userInfo = null;
        if (redisDao.existsKey(token)) {
            userInfo = JwtUtil.getUserInfoFromToken(token, redisDao);
            Training training = new Training();
            BeanUtil.copyProperties(dto, training);
            PageHelper.startPage(dto.getPage(), dto.getRows());
            List<Training> tbTrainingList = trainingDao.queryDataList(training);
            PageInfo<Training> pageInfo = new PageInfo<Training>(tbTrainingList, dto.getRows());
            Map<String, Object> resutMap = new HashMap();
            resutMap.put("total", pageInfo.getTotal());
            resutMap.put("rows", pageInfo.getList());
            result.setCode(200);
            result.setMsg("获取成功");
            result.setData(resutMap);
            logService.logAdd(null, "获取培训课程列表", "SUCCESS", result.toString(), userInfo, request);
        } else {
            result.setCode(-1);
            result.setMsg("登录超时");
            logService.logAdd(null, "获取培训课程列表", "ERROR", result.toString(), userInfo, request);
        }
        return result;
    }

    @Override
    public Result findDataById(Integer id, HttpServletRequest request) {
        Result result = Result.success(null, "培训课程信息获取成功");
        String token = request.getHeader("token");
        UserInfo userInfo = null;
        if (redisDao.existsKey(token)) {
            userInfo = JwtUtil.getUserInfoFromToken(token, redisDao);
            //主要业务逻辑
            Training training = trainingDao.findDataById(id);
            TrainingVo vo = new TrainingVo();
            BeanUtils.copyProperties(training, vo);
            Att att = new Att();
            att.setState(1);
            att.setBizType("1006");
            att.setDataNo(id);
            List<Att> atts = attDao.queryDataList(att);
            for (Att a : atts) {
                String s = a.getAttName().substring(a.getAttName().lastIndexOf(".") + 1);
                Map<String, String> map = new HashMap<>();
                map.put("name", a.getAttName());
                map.put("path", a.getAttPath());
                map.put("link", a.getDldLink());
                map.put("fileSize",String.valueOf(a.getAttSize()));
                switch (s) {
                    case "mp3":
                        if (null == vo.getAudios()) {
                            List<Map<String, String>> audios = new ArrayList<>();
                            audios.add(map);
                            vo.setAudios(audios);
                        } else {
                            vo.getAudios().add(map);
                        }
                        break;
                    case "mp4":
                        if (null == vo.getVideos()) {
                            List<Map<String, String>> videos = new ArrayList<>();
                            videos.add(map);
                            vo.setVideos(videos);
                        } else {
                            vo.getVideos().add(map);
                        }
                        break;
                    case "jpg":
                    case "jpeg":
                    case "png":
                        if (null == vo.getPictures()) {
                            List<Map<String, String>> pictures = new ArrayList<>();
                            pictures.add(map);
                            vo.setPictures(pictures);
                        } else {
                            vo.getPictures().add(map);
                        }
                        break;
                    default:
                        if (null == vo.getFiles()) {
                            List<Map<String, String>> files = new ArrayList<>();
                            files.add(map);
                            vo.setFiles(files);
                        } else {
                            vo.getFiles().add(map);
                        }
                        break;
                }
            }
            result.setData(vo);
            this.updateVisitNum(training);
            logService.logAdd(null, "获取培训课程信息表对象", "SUCCESS", result.toString(), userInfo, request);
        } else {
            result.setCode(-1);
            result.setMsg("登录超时");
            logService.logAdd(null, "获取培训课程信息表对象", "ERROR", result.toString(), userInfo, request);
        }
        return result;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result saveData(TrainingAddDto dto, HttpServletRequest request) {
        Result result = new Result();
        String token = request.getHeader("token");
        UserInfo userInfo = null;
        if (redisDao.existsKey(token)) {
            userInfo = JwtUtil.getUserInfoFromToken(token, redisDao);
            Training training = new Training();
            BeanUtil.copyProperties(dto, training);
            if ((dto.getEndTime().compareTo(dto.getBeginTime()))<=0
                    || (dto.getDeadline().compareTo(dto.getRegistrationTime()))<=0 ||
                    (dto.getBeginTime().compareTo(dto.getDeadline()))<0){
                result.setCode(ResultEnum.BADREQUEST.getCode());
                result.setMsg("传入的日期参数有误");
                return result;
            }
            if (ObjectUtil.isNotNull(training.getId()) && training.getId() > 0) {
                trainingDao.updateDataById(training);
            } else {
                training.setCreateId(userInfo.getUserId());
                training.setTrainingCode(CodeGenerateUtil.getNewEquipmentNoByTime(CodeGenerateUtil.PRE_TRAINING_CODE));
                trainingDao.insertData(training);
                //添加审核节点
                ApplyLc applyLc = new ApplyLc();
                applyLc.setBizType(BizTypeEnum.Em_Training.getValue());
                applyLc.setBizId(training.getId());
                applyLc.setReqState(1);
                applyLc.setLcId("lc_001");
                applyLc.setResultCode(OperEnum.Em_Add.getValue());
                applyLc.setResultDsc(OperEnum.Em_Add.getName());
                applyLc.setOpr(userInfo.getUserId());
                applyLc.setOpTime(new Date());
                applyLc.setState(2);
                commDao.saveApply(applyLc);

                ApplyStateToNext stateToNext = new ApplyStateToNext();
                stateToNext.setBizType(BizTypeEnum.Em_Training.getValue());
                stateToNext.setReqState(1);
                stateToNext.setNowLcId("lc_001");
                stateToNext.setOp(OperEnum.Em_Add.getValue());
                ApplyStateToNext nextFlowInfo = commDao.getNextFlowInfo(stateToNext);

                Task task = new Task();
                task.setBizType(BizTypeEnum.Em_Training.getValue());
                task.setTitle(dto.getName() + "课程发布审核");
                task.setBizId(training.getId());
                task.setLcId(nextFlowInfo.getNextLcId());
                task.setLcName(nextFlowInfo.getNextLcName());
                task.setCUser(userInfo.getUserId());
                task.setState(1);
                commDao.saveTask(task);

                applyLc = new ApplyLc();
                applyLc.setBizType(BizTypeEnum.Em_Training.getValue());
                applyLc.setBizId(training.getId());
                applyLc.setReqState(1);
                if (StrUtil.isNotEmpty(nextFlowInfo.getNextLcId())) {
                    applyLc.setLcId(nextFlowInfo.getNextLcId());
                }
                applyLc.setState(1);
                commDao.saveApply(applyLc);
            }
            //附件处理
            if (dto.getFiles().size() > 0) {
                int bizId = 0;
                if (dto.getId() != null && dto.getId() > 0) {
                    bizId = dto.getId();
                } else {
                    bizId = training.getId();
                }
                attDao.deleteDataByDataNo(String.valueOf(bizId), BizTypeEnum.Em_Training.getValue());
                for (TrainAttDto attDto : dto.getFiles()) {
                    Att att = new Att();
                    att.setBizType(BizTypeEnum.Em_Training.getValue());
                    if (dto.getId() != null && dto.getId() > 0) {
                        att.setDataNo(dto.getId());
                    } else {
                        att.setDataNo(training.getId());
                    }
                    att.setcUser(userInfo.getUserId());
                    if (attDto.getAttName() == null && attDto.getName() != null){
                        att.setAddType(getExtName(attDto.getName()));
                        att.setAttName(attDto.getName());
                    } else if (attDto.getName()==null && attDto.getAttName()!=null) {
                        att.setAddType(getExtName(attDto.getAttName()));
                        att.setAttName(attDto.getAttName());
                    } else if (attDto.getAttName() != null && attDto.getName() != null) {
                        att.setAddType(getExtName(attDto.getName()));
                        att.setAttName(attDto.getName());
                    }
                    if (attDto.getPath() == null && attDto.getAttPath() != null){
                        att.setAttPath(attDto.getAttPath());
                    } else if (attDto.getPath() != null && attDto.getAttPath() == null) {
                        att.setAttPath(attDto.getPath());
                    }else {
                        att.setAttPath(attDto.getAttPath());
                    }
                    if (attDto.getUrl() != null && attDto.getLink() == null){
                        att.setDldLink(attDto.getUrl());
                    } else if (attDto.getUrl() == null && attDto.getLink() != null) {
                        att.setDldLink(attDto.getLink());
                    }
                    att.setAttSize(attDto.getFileSize());
                    attDao.insertData(att);
                }
            }

            result.setCode(200);
            result.setMsg("操作成功");
            result.setData(training);
            logService.logAdd(null, "保存培训课程信息", "SUCCESS", result.toString(), userInfo, request);
        } else {
            result.setCode(-1);
            result.setMsg("登录超时");
            logService.logAdd(null, "保存培训课程信息", "ERROR", result.toString(), userInfo, request);
        }
        return result;
    }

    private String getExtName(String attName) {
        int i = attName.lastIndexOf('.');
        int leg = attName.length();
        return i > 0 ? (i + 1) == leg ? " " : attName.substring(i + 1) : " ";

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result deleteDataById(Integer id, HttpServletRequest request) {
        Result result = new Result();
        String token = request.getHeader("token");
        UserInfo userInfo = null;
        if (redisDao.existsKey(token)) {
            userInfo = JwtUtil.getUserInfoFromToken(token, redisDao);
            trainingDao.deleteDataById(id);
            //删除对应的文件
            attDao.deleteDataByDataNo(id.toString(), BizTypeEnum.Em_Training.getValue());

            result.setCode(200);
            result.setMsg("操作成功");
            logService.logAdd(null, "删除培训课程信息表对象", "SUCCESS", result.toString(), userInfo, request);
        } else {
            result.setCode(-1);
            result.setMsg("登录超时");
            logService.logAdd(null, "删除培训课程信息表对象", "ERROR", result.toString(), userInfo, request);
        }

        return result;
    }

    public void updateVisitNum(Training training) {
        Training dataById = trainingDao.findDataById(training.getId());
        Integer visitNum = dataById.getVisitNum() == null ? 0 : dataById.getVisitNum();
        training.setVisitNum(visitNum + 1);
        trainingDao.updateVisitNum(training);
    }

}
